package com.unicom.mec.device.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.unicom.mec.common.constants.KubernetesConstants;
import com.unicom.mec.common.enums.device.AccessStatus;
import com.unicom.mec.common.enums.device.EdgeNodeType;
import com.unicom.mec.common.enums.device.RunStatus;
import com.unicom.mec.device.common.ResultBean;
import com.unicom.mec.device.mapper.EdgeNodeMapper;
import com.unicom.mec.device.model.EdgeNode;
import com.unicom.mec.device.remote.UserRemote;
import com.unicom.mec.device.util.NodeRunInfoUtil;
import com.unicom.mec.device.vo.EdgeNodeStatisticVo;
import com.unicom.mec.device.vo.EdgeNodeVo;
import com.unicom.mec.device.vo.EditEdgeNodeVo;
import io.kubernetes.client.openapi.ApiException;
import io.kubernetes.client.openapi.apis.CoreV1Api;
import io.kubernetes.client.openapi.models.V1NodeList;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 边缘节点业务层实现
 *
 * @author 刘亮武
 * @date 2020年06月17日
 */
@Service
public class EdgeNodeServiceImpl implements EdgeNodeService {

    @Autowired
    private CoreV1Api coreV1Api;
    @Autowired
    private UserRemote userRemote;
    @Autowired
    private EdgeNodeMapper edgeNodeMapper;

    @Override
    public void findEdgeNodesForTask() {
        try {
            V1NodeList v1NodeList = coreV1Api.listNode(null, null, null, null, null, null, null, null, null);
            v1NodeList.getItems().forEach(v1Node -> {
                String edgeNodeKey = v1Node.getMetadata().getLabels().get(KubernetesConstants.EDGE_NODE_KEY);
                QueryWrapper<EdgeNode> edgeNodeQuery = new QueryWrapper<>();
                edgeNodeQuery.eq("edge_node_key", edgeNodeKey);
                List<EdgeNode> edgeNodes = edgeNodeMapper.selectList(edgeNodeQuery);
                // 不存在边缘节点
                if (CollectionUtils.isEmpty(edgeNodes)) {
                    String uniqueKey = v1Node.getMetadata().getLabels().get(KubernetesConstants.TENANT_UNIQUE_KEY);
                    if (StringUtils.isNotBlank(uniqueKey)) {
                        ResultBean<Long> result = userRemote.findTenantIdByUniqueKey(uniqueKey);
                        EdgeNode edgeNode = new EdgeNode();
                        edgeNode.setId(IdWorker.getId());
                        edgeNode.setTenantId(result.getData());
                        edgeNode.setEdgeNodeKey(edgeNodeKey);
                        String type = v1Node.getMetadata().getLabels().get(KubernetesConstants.EDGE_TYPE);
                        if (KubernetesConstants.EDGE_TYPE_A.equals(type)) {
                            edgeNode.setEdgeNodeType(EdgeNodeType.计算节点.getValue());
                        } else {
                            edgeNode.setEdgeNodeType(EdgeNodeType.展示节点.getValue());
                        }
                        edgeNode.setAccessStatus(AccessStatus.未接入.getValue());
                        edgeNode.setArch(v1Node.getMetadata().getLabels().get(KubernetesConstants.ARCH));
                        edgeNode.setIp(v1Node.getMetadata().getLabels().get(KubernetesConstants.IP));
                        edgeNode.setCpu(v1Node.getStatus().getCapacity().get(KubernetesConstants.CPU).getNumber().intValue());
                        System.out.println(v1Node.getStatus().getCapacity().get(KubernetesConstants.MEMORY));
                        edgeNode.setMemory((int)(v1Node.getStatus().getCapacity().get(KubernetesConstants.MEMORY).getNumber().longValue() / 1024 / 1024));
                        edgeNode.setHardDisk(v1Node.getStatus().getCapacity().get(KubernetesConstants.HARD_DISK).getNumber().longValue() / 1024 / 1024);
                        Map<String, Object> runInfo = NodeRunInfoUtil.getRunInfo(v1Node.getStatus().getConditions());
                        edgeNode.setRunStatus((Integer) runInfo.get(NodeRunInfoUtil.RUN_STATUS));
                        edgeNode.setRunTime((String) runInfo.get(NodeRunInfoUtil.RUN_TIME));
                        edgeNode.setCreateId(result.getData());
                        edgeNode.setCreateTime(new Date());
                        edgeNodeMapper.insert(edgeNode);
                    }
                }
                // 存在边缘节点
                else{
                    EdgeNode edgeNode = edgeNodes.get(0);
                    Map<String, Object> runInfo = NodeRunInfoUtil.getRunInfo(v1Node.getStatus().getConditions());
                    edgeNode.setRunStatus((Integer) runInfo.get(NodeRunInfoUtil.RUN_STATUS));
                    edgeNode.setRunTime((String) runInfo.get(NodeRunInfoUtil.RUN_TIME));
                    edgeNode.setUpdateId(edgeNode.getCreateId());
                    edgeNode.setUpdateTime(new Date());
                    edgeNodeMapper.updateById(edgeNode);
                }
            });
        } catch (ApiException e) {
            e.printStackTrace();
        }
    }

    @Override
    public List<EdgeNodeVo> findEdgeNodes(Long tenantId) {
        return edgeNodeMapper.findEdgeNodes(tenantId);
    }

    @Override
    public EdgeNodeStatisticVo findEdgeNodeStatistic(Long tenantId) {
        EdgeNodeStatisticVo edgeNodeStatisticVo = new EdgeNodeStatisticVo();
        QueryWrapper<EdgeNode> edgeQuery = new QueryWrapper<>();
        if(tenantId != null){
            edgeQuery.eq("tenant_id",tenantId);
        }
        edgeQuery.eq("access_status",AccessStatus.已接入.getValue());
        Integer totalCount = edgeNodeMapper.selectCount(edgeQuery);
        edgeNodeStatisticVo.setTotalCount(totalCount);
        edgeQuery.eq("run_status", RunStatus.运行.getValue());
        Integer runCount = edgeNodeMapper.selectCount(edgeQuery);
        edgeNodeStatisticVo.setRunCount(runCount);
        return edgeNodeStatisticVo;
    }

    @Override
    public Page<EdgeNodeVo> findAccessEdgeNodes(Long tenantId, Integer page, Integer pageSize) {
        Page searchPage = new Page(page, pageSize);
        return edgeNodeMapper.findEdgeNodesForPage(searchPage, tenantId, AccessStatus.已接入.getValue());
    }

    @Override
    public Page<EdgeNodeVo> findNoAccessEdgeNodes(Long tenantId, Integer page, Integer pageSize) {
        Page searchPage = new Page(page, pageSize);
        return edgeNodeMapper.findEdgeNodesForPage(searchPage, tenantId, AccessStatus.未接入.getValue());
    }

    @Override
    public EdgeNodeVo findEdgeNodeById(Long id) {
        return edgeNodeMapper.findEdgeNodeById(id);
    }

    @Override
    public void editEdgeNode(EditEdgeNodeVo editEdgeNodeVo) {
        EdgeNode edgeNode = edgeNodeMapper.selectById(editEdgeNodeVo.getId());
        edgeNode.setEdgeNodeName(editEdgeNodeVo.getEdgeNodeName());
        edgeNode.setEdgeNodeDesc(editEdgeNodeVo.getEdgeNodeDesc());
        edgeNode.setLongitude(editEdgeNodeVo.getLongitude());
        edgeNode.setLatitude(editEdgeNodeVo.getLatitude());
        if(AccessStatus.已接入.getValue() == editEdgeNodeVo.getAccessStatus()){
            edgeNode.setAccessStatus(editEdgeNodeVo.getAccessStatus());
            edgeNode.setAccessTime(new Date());
        }
        edgeNodeMapper.updateById(edgeNode);
    }
}
